﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;


namespace Devtm.ServiceModel.Proxy.Events
{


    /// <summary>
    /// base for the event args interception
    /// </summary>
    public class InterceptEventArgs : EventArgs
    {



        private Hashtable parameters = null;
        private Object[] _Valueparameters;


        internal InterceptEventArgs(System.Reflection.MethodBase methodBase, object[] parameters)
        {

            // TODO: Complete member initialization
            this.Method = methodBase as System.Reflection.MethodInfo;
            this._Valueparameters = parameters;

        }


        /// <summary>
        /// get the Parameter specified by name.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <returns></returns>
        public Parameter Parameter(string name)
        {
            var i = Parameters;
            return i[name] as Parameter;
        }

        
        /// <summary>
        /// return the list of parameters
        /// </summary>
        public Hashtable Parameters
        {

            get
            {
                if (parameters == null)
                {

                    parameters = new Hashtable();
                    System.Reflection.ParameterInfo[] _p1 = Method.GetParameters();

                    for (int i = 0; i < _p1.Length; i++)
                    {
                        Parameter p2 = new Parameter(_p1[i], _Valueparameters[i], _p1[i].Name ?? "p" + i);
                        parameters.Add(p2.Name, p2);
                    }

                }

                return parameters;
            }
        }


        /// <summary>
        /// return the client proxy
        /// </summary>
        public Devtm.ServiceModel.Proxy.ClientBase Proxy { get; set; }


        /// <summary>
        /// Return the working service
        /// for the wcf calls, this the channel.
        /// </summary>
        public object Service { get; set; }


        /// <summary>
        /// Gets or sets the asked interface.
        /// </summary>
        /// <value>The interface.</value>
        public Type Interface { get; set; }

        /// <summary>
        /// Gets or sets the method info.
        /// </summary>
        /// <value>The method.</value>
        public System.Reflection.MethodInfo Method { get; private set; }

    }


    /// <summary>
    /// Parameter information
    /// </summary>
    public class Parameter
    {

        private System.Reflection.ParameterInfo _parameter;

        /// <summary>
        /// Initializes a new instance of the <see cref="Parameter"/> class.
        /// </summary>
        /// <param name="parameter">The parameter.</param>
        /// <param name="value">The value.</param>
        /// <param name="name">The name.</param>
        internal Parameter(System.Reflection.ParameterInfo parameter, object value, string name)
        {
            _parameter = parameter;
            Value = value;
            Name = name;
        }


        /// <summary>
        /// Gets a value indicating whether this is an input parameter.
        /// return true if the parameter is an input parameter; otherwise, false
        /// </summary>        
        public bool IsIn { get { return _parameter.IsIn; } }


        /// <summary>
        /// Gets a value indicating whether this parameter is a locale identifier (lcid).
        /// return true if the parameter is a locale identifier; otherwise, false.
        /// </summary>
        public bool IsLcid { get { return _parameter.IsLcid; } }


        /// <summary>
        /// Gets a value indicating whether this parameter is optional.
        /// return true if the parameter is optional; otherwise, false.
        /// </summary>
        public bool IsOptional { get { return _parameter.IsOptional; } }


        /// <summary>
        /// Gets a value indicating whether this is an output parameter.
        /// return true if the parameter is an output parameter; otherwise, false.
        /// </summary>
        public bool IsOut { get { return _parameter.IsOut; } }


        /// <summary>
        /// Gets a value indicating whether this is a Retval parameter.
        // return true if the parameter is a Retval; otherwise, false.
        /// </summary>
        public bool IsRetval { get { return _parameter.IsRetval; } }


        /// <summary>
        /// Gets a value indicating the Method in which the parameter is implemented.
        // return A MethodInfo object.
        /// </summary>
        public System.Reflection.MethodInfo Method { get { return _parameter.Member as System.Reflection.MethodInfo; } }


        /// <summary>
        /// Gets the name of the parameter.
        /// </summary>
        public string Name { get; private set; }


        /// <summary>
        /// Gets the Type of this parameter.
        /// </summary>
        public Type Type { get { return _parameter.ParameterType; } }


        /// <summary>
        /// Gets the zero-based position of the parameter in the formal parameter list.
        /// return An integer representing the position this parameter occupies in the parameter list.
        /// </summary>
        public int Position { get { return _parameter.Position; } }


        /// <summary>
        /// return the value in the called method
        /// </summary>
        public object Value { get; private set; }


    }

}
